{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## python中的类"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 类是什么\n",
    "介绍类之前，先介绍一个类的实例"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](http://i4.fuimg.com/611786/60bdfadccfc93ac5.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对马里奥来说，我们可以描述他的诸多特征：\n",
    "+ 大鼻子\n",
    "+ 红帽子\n",
    "+ 蓝色背带裤\n",
    "+ 红色衬衣\n",
    "+ 还留着胡子\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](http://i4.fuimg.com/611786/c4071b1e8f23165e.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对马里奥来说，不仅仅是一个静止的形象，还是一个活蹦乱跳的游戏人物：\n",
    "+ 跑\n",
    "+ 跳、三级跳、远跳\n",
    "+ 下蹲\n",
    "+ 翻滚\n",
    "+ 空中小幅移动\n",
    "+ 后空翻、侧空翻\n",
    "+ 扔帽子\n",
    "+ 游泳\n",
    "+ ......"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](http://i4.fuimg.com/611786/366e2653983d3b15.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](http://i4.fuimg.com/611786/cda28515c3520f92.gif)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](http://i4.fuimg.com/611786/9afa2e58b62149a0.gif)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](http://i2.tiimg.com/611786/61a74b5b1117cf31.gif)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 总结下，马里奥：\n",
    "+ 有一些特征\n",
    "+ 有一些“预装”好的操作，或者叫“主角光环”、“人设”等等\n",
    "+ “血”掉光了后，重新来过，又有一个新的马里奥\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 在python的类里，称之为：\n",
    "\n",
    "+ 属性(其实就是变量)\n",
    "+ 方法（很像函数）\n",
    "+ 类和实例"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 类的概念概括性很强：\n",
    "+ 贫困\n",
    "    + 阿马蒂亚.森：“可行能力”的贫困\n",
    "    + 收入是不是贫困的特征呢？\n",
    "    + 贫困的特征应该是指向获取美好生活的行动的\n",
    "+ 依恋类型\n",
    "    + 一种人格分类\n",
    "    + 不同的类都有自己的特征和基本稳定的一些恋爱过程中表现(方法、操作等)\n",
    "    + 你遇到的每个人都是类里的一些实例"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 类里设定属性的值"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 例子：依恋类型里的倾注型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "class preoccupied():\n",
    "    def __init__(self):\n",
    "        self.zhui = True\n",
    "        self.fenshou = False\n",
    "        self.manyi = False\n",
    "        self.jiji = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class '__main__.preoccupied'>\n"
     ]
    }
   ],
   "source": [
    "boyfriend = preoccupied\n",
    "print(boyfriend)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 倾注型的特点：\n",
    "+ “宁可错杀一千也不放过一个”\n",
    "+ 天天吵闹要分手，却迟迟不走\n",
    "+ 无论你做什么，都对你不满意，嫌你对TA不好\n",
    "+ 甚少做出有利于关心的行为"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 《冰雨》\n",
    "  \n",
    "我是在等待一个女孩  \n",
    "还是在等待沉沦苦海  \n",
    "一段情默默灌溉  \n",
    "没有人去管花谢花开  \n",
    "无法肯定的爱 左右摇摆  \n",
    "只好把心酸往深心里塞  \n",
    "......  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [],
   "source": [
    "class preoccupied():\n",
    "    def __init__(self):\n",
    "        self.zhui = True\n",
    "        self.fenshou = False\n",
    "        self.manyi = False\n",
    "        self.jiji = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "mounan = preoccupied()\n",
    "print(mounan.zhui)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 传递参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class preoccupied():\n",
    "    def __init__(self):\n",
    "        self.zhui = True\n",
    "        self.fenshou = False\n",
    "        self.manyi = False\n",
    "        self.jiji = False\n",
    "    \n",
    "    def xiangqin(self,girl):\n",
    "        if girl == 'beautiful' :\n",
    "            self.zhui = self.zhui\n",
    "        else :\n",
    "            self.zhui = self.zhui or True \n",
    "            \n",
    "    def chaojia(self,chengdu,cishu):\n",
    "        if chengdu > 5 or cishu>1000:\n",
    "            self.fenshou = True\n",
    "        else :\n",
    "            self.fenshou = self.fenshou "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n",
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "mounan = preoccupied()\n",
    "print(mounan.zhui)\n",
    "\n",
    "#### 抓住机会\n",
    "mounan.xiangqin(girl = \"ugly\")\n",
    "print(mounan.zhui)\n",
    "\n",
    "#### 一般的吵架不分手\n",
    "mounan.chaojia(chengdu = 4,cishu = 20)\n",
    "print(mounan.fenshou)\n",
    "\n",
    "#### 超的少了不分手\n",
    "mounan.chaojia(chengdu = 3,cishu = 1001)\n",
    "print(mounan.fenshou)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 类里不设定，生成实例时赋予属性值"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 上例再一般化一些，我们认为可以从追、分手、满意、积极这几个方面来看人在恋爱中表现的话。\n",
    "+ 不预先赋值\n",
    "+ 生成实例的时候再赋值\n",
    "+ 方法保持不变"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [],
   "source": [
    "class preoccupied(object):\n",
    "    def __init__(self,x1,x2,x3,x4): ## 需要定义传递的值\n",
    "        self.zhui = x1\n",
    "        self.fenshou = x2\n",
    "        self.manyi = x3\n",
    "        self.jiji = x4\n",
    "    \n",
    "    def xiangqin(self,girl):\n",
    "        if girl == 'beautiful' :\n",
    "            self.zhui = self.zhui\n",
    "        else :\n",
    "            self.zhui = self.zhui or True \n",
    "            \n",
    "    def chaojia(self,chengdu,cishu):\n",
    "        if chengdu > 5 or cishu>1000:\n",
    "            self.fenshou = True\n",
    "        else :\n",
    "            self.fenshou = self.fenshou "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "mounan = preoccupied(True, False, False, False)\n",
    "\n",
    "#### 抓住机会\n",
    "mounan.xiangqin(girl = \"ugly\")\n",
    "print(mounan.zhui)\n",
    "\n",
    "#### 一般的吵架不分手\n",
    "mounan.chaojia(chengdu = 4,cishu = 20)\n",
    "print(mounan.fenshou)\n",
    "\n",
    "#### 超的少了不分手\n",
    "mounan.chaojia(chengdu = 3,cishu = 1001)\n",
    "print(mounan.fenshou)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 创建多个实例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "class preoccupied(object):\n",
    "    def __init__(self,x1,x2,x3,x4): ## 需要定义传递的值\n",
    "        self.zhui = x1\n",
    "        self.fenshou = x2\n",
    "        self.manyi = x3\n",
    "        self.jiji = x4\n",
    "    \n",
    "    def xiangqin(self,girl):\n",
    "        if girl == 'beautiful' :\n",
    "            self.zhui = self.zhui\n",
    "        else :\n",
    "            self.zhui = self.zhui or True \n",
    "            \n",
    "    def chaojia(self,chengdu,cishu):\n",
    "        if chengdu > 5 or cishu>1000:\n",
    "            self.fenshou = True\n",
    "        else :\n",
    "            self.fenshou = self.fenshou \n",
    "\n",
    "yixieren = []\n",
    "\n",
    "yixieren.append(preoccupied(False, False, False, False))\n",
    "yixieren.append(preoccupied(True, False, False, False))\n",
    "yixieren.append(preoccupied(True, False, False, True))\n",
    "\n",
    "for index, man in enumerate(yixieren):\n",
    "    print(mounan.fenshou)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 改变方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [],
   "source": [
    "class preoccupied(object):\n",
    "    def __init__(self,x1,x2,x3,x4): ## 需要定义传递的值\n",
    "        self.zhui = x1\n",
    "        self.fenshou = x2\n",
    "        self.manyi = x3\n",
    "        self.jiji = x4\n",
    "    \n",
    "    def xiangqin(self,girl):\n",
    "        if girl == 'beautiful' : # 好看才追\n",
    "            self.zhui = True\n",
    "        else :\n",
    "            self.zhui = self.zhui # 不好看取决于我的人格特质\n",
    "            \n",
    "    def chaojia(self,chengdu,cishu):\n",
    "        if chengdu > 5 or cishu>1000:\n",
    "            self.fenshou = True\n",
    "        else :\n",
    "            self.fenshou = self.fenshou "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "mounan = preoccupied(False, False, False, False)\n",
    "\n",
    "#### 抓住机会\n",
    "mounan.xiangqin(girl = \"ugly\")\n",
    "print(mounan.zhui)\n",
    "\n",
    "#### 一般的吵架不分手\n",
    "mounan.chaojia(chengdu = 4,cishu = 20)\n",
    "print(mounan.fenshou)\n",
    "\n",
    "#### 超的少了不分手\n",
    "mounan.chaojia(chengdu = 3,cishu = 1001)\n",
    "print(mounan.fenshou)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 练习：学生信息\n",
    "+ 创建一个类，包含姓名、分数、睡眠时间三个属性\n",
    "+ 包含一个胖瘦的预测，如果分数>90，且睡眠时间少于6小时，输出“BMI可能偏大”，否则输出“体重正常”\n",
    "+ 为使得标准（90分、6小时）可以调整，应设为输入的参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Student(object):\n",
    " \n",
    "  def __init__(self, name, score):\n",
    "    self.name = name\n",
    "    self.score = score\n",
    "  \n",
    "  def get_grade(self,c1,c2):\n",
    "    if self.score >= c1:\n",
    "      return 'A'\n",
    "    elif self.score >= c2:\n",
    "      return 'B'\n",
    "    else:\n",
    "      return 'C'  \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'韩梅梅'"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stu = Student('韩梅梅', 89)\n",
    "stu.name\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'B'"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stu.get_grade(90,60)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 类的继承"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 马里奥的历史很悠久\n",
    "+ 有很早期的街机\n",
    "+ 红白机\n",
    "+ .......\n",
    "+ switch\n",
    "\n",
    "但是他的一些基本特征和操作，一直保留下来，后期的马里奥都继承了之前版本的经典部分"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 定义一个火箭"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The rockets are 11.180340 units apart.\n"
     ]
    }
   ],
   "source": [
    "from math import sqrt\n",
    "\n",
    "class Rocket():\n",
    "    # Rocket simulates a rocket ship for a game,\n",
    "    #  or a physics simulation.\n",
    "    \n",
    "    def __init__(self, x=0, y=0):\n",
    "        # Each rocket has an (x,y) position.\n",
    "        self.x = x\n",
    "        self.y = y\n",
    "        \n",
    "    def move_rocket(self, x_increment=0, y_increment=1):\n",
    "        # Move the rocket according to the paremeters given.\n",
    "        #  Default behavior is to move the rocket up one unit.\n",
    "        self.x += x_increment\n",
    "        self.y += y_increment\n",
    "        \n",
    "    def get_distance(self, other_rocket):\n",
    "        # Calculates the distance from this rocket to another rocket,\n",
    "        #  and returns that value.\n",
    "        distance = sqrt((self.x-other_rocket.x)**2+(self.y-other_rocket.y)**2)\n",
    "        return distance\n",
    "    \n",
    "rocket_0 = Rocket()\n",
    "rocket_1 = Rocket(10,5)\n",
    "\n",
    "# Show the distance between them.\n",
    "distance = rocket_0.get_distance(rocket_1)\n",
    "print(\"The rockets are %f units apart.\" % distance)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 航天飞机继承了火箭"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "The shuttle are 11.180340 units apart.\n"
     ]
    }
   ],
   "source": [
    "class Shuttle(Rocket):\n",
    "    # Shuttle simulates a space shuttle, which is really\n",
    "    #  just a reusable rocket.\n",
    "    \n",
    "    def __init__(self, x=0, y=0, flights_completed=0):\n",
    "        super().__init__(x, y)                      ## 通过super函数声明继承了父类的属性\n",
    "        self.flights_completed = flights_completed\n",
    "        \n",
    "shuttle = Shuttle(10,0,3)\n",
    "print(shuttle.flights_completed)\n",
    "\n",
    "\n",
    "\n",
    "rocket_0 = Shuttle()\n",
    "rocket_1 = Shuttle(10,5,3)\n",
    "\n",
    "# Show the distance between them.\n",
    "distance = rocket_0.get_distance(rocket_1)\n",
    "print(\"The shuttle are %f units apart.\" % distance)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
